{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tqdm import *\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append('LLMs-Planning/llm_planning_analysis')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from Executor import Executor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_path = \"LLMs-Planning/llm_planning_analysis/instances/blocksworld/generated_basic\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"gpt-plan-benchmark/gpt_plan_test\")\n",
    "from Executor import Executor\n",
    "# from reasoners.benchmark.bw_utils import *\n",
    "from utils import *\n",
    "from pathlib import Path\n",
    "from tarski.io import PDDLReader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_problem(instance, domain):\n",
    "    reader = PDDLReader(raise_on_error=True)\n",
    "    reader.parse_domain(domain)\n",
    "    return reader.parse_instance(instance)\n",
    "def get_executor(instance, domain):\n",
    "    plan_executor = Executor(domain, instance)\n",
    "    return plan_executor\n",
    "def compute_plan(domain, instance, timeout=30):\n",
    "    fast_downward_path = os.getenv(\"FAST_DOWNWARD\")\n",
    "    # Remove > /dev/null to see the output of fast-downward\n",
    "    assert os.path.exists(f\"{fast_downward_path}/fast-downward.py\")\n",
    "    '''\n",
    "    cmd = f\"{fast_downward_path}/fast-downward.py --log-level debug --translate {domain} {instance} > /dev/null 2>&1\"\n",
    "    os.system(cmd)\n",
    "    time.sleep(0.5)\n",
    "    cmd = f\"{fast_downward_path}/fast-downward.py --log-level debug output.sas --search-options --search  \\\"astar(lmcut())\\\" > /dev/null 2>&1\" \n",
    "    os.system(cmd)\n",
    "    time.sleep(0.5)\n",
    "    '''\n",
    "    if os.path.exists(\"sas_plan\"):\n",
    "        try:\n",
    "            os.remove(\"sas_plan\")\n",
    "        except Exception as e:\n",
    "            print(e)\n",
    "\n",
    "    while not os.path.exists(\"sas_plan\"):\n",
    "        cmd = f\"timeout {timeout}s {fast_downward_path}/fast-downward.py --log-level debug {domain} {instance} --search \\\"astar(lmcut())\\\"  > /dev/null 2>&1\"\n",
    "        # print(cmd)\n",
    "        os.system(cmd)\n",
    "        time.sleep(2)\n",
    "        \n",
    "    \n",
    "    if not os.path.exists(\"sas_plan\"):\n",
    "        print(\"Plan failed\")\n",
    "        return \"\"\n",
    "    \n",
    "    return Path(\"sas_plan\").read_text()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "config_file = \"examples/rap_blocksworld/data/bw_config.yaml\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import yaml\n",
    "def read_config(config_file):\n",
    "    with open(config_file, 'r') as file:\n",
    "        data = yaml.safe_load(file)\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "domain_pddl = \"examples/rap_blocksworld/data/generated_domain.pddl\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = read_config(config_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "# re.findall(\"\\(.*?\\)\", \"(cc d), (ds)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/501 [00:02<?, ?it/s]\n"
     ]
    }
   ],
   "source": [
    "from tqdm import *\n",
    "my_data = []\n",
    "for i in tqdm(os.listdir(data_path)):\n",
    "    if i.endswith(\".pddl\"):\n",
    "        data_file = os.path.join(data_path, i)\n",
    "        # print(i)\n",
    "    else:\n",
    "        print(\"Not pddl file\", i)\n",
    "        continue\n",
    "    cur_instance = data_file\n",
    "    problem = get_problem(cur_instance, domain_pddl)\n",
    "    gt_plan = compute_plan(domain_pddl, cur_instance)\n",
    "    gt_plan_text = get_plan_as_text(data)\n",
    "    break\n",
    "    my_data.append((cur_instance, gt_plan_text, len(re.findall(\"\\(.*?\\)\", gt_plan_text))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "val_path = os.getenv(\"VAL\")\n",
    "cmd = f\"{val_path}/validate -v {domain_pddl} {cur_instance} sas_plan\"\n",
    "response = os.popen(cmd).read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Checking plan: sas_plan\n",
      "Plan to validate:\n",
      "\n",
      "Plan size: 10\n",
      "1:\n",
      "(unstack a c)\n",
      " \n",
      "2:\n",
      "(put-down a)\n",
      " \n",
      "3:\n",
      "(unstack c d)\n",
      " \n",
      "4:\n",
      "(stack c a)\n",
      " \n",
      "5:\n",
      "(unstack d b)\n",
      " \n",
      "6:\n",
      "(put-down d)\n",
      " \n",
      "7:\n",
      "(unstack c a)\n",
      " \n",
      "8:\n",
      "(stack c d)\n",
      " \n",
      "9:\n",
      "(pick-up b)\n",
      " \n",
      "10:\n",
      "(stack b c)\n",
      " \n",
      "\n",
      "Plan Validation details\n",
      "-----------------------\n",
      "\n",
      "Checking next happening (time 1)\n",
      "Deleting (on a c)\n",
      "Deleting (clear a)\n",
      "Deleting (handempty)\n",
      "Adding (holding a)\n",
      "Adding (clear c)\n",
      "\n",
      "Checking next happening (time 2)\n",
      "Deleting (holding a)\n",
      "Adding (clear a)\n",
      "Adding (handempty)\n",
      "Adding (ontable a)\n",
      "\n",
      "Checking next happening (time 3)\n",
      "Deleting (on c d)\n",
      "Deleting (clear c)\n",
      "Deleting (handempty)\n",
      "Adding (holding c)\n",
      "Adding (clear d)\n",
      "\n",
      "Checking next happening (time 4)\n",
      "Deleting (clear a)\n",
      "Deleting (holding c)\n",
      "Adding (handempty)\n",
      "Adding (clear c)\n",
      "Adding (on c a)\n",
      "\n",
      "Checking next happening (time 5)\n",
      "Deleting (on d b)\n",
      "Deleting (clear d)\n",
      "Deleting (handempty)\n",
      "Adding (holding d)\n",
      "Adding (clear b)\n",
      "\n",
      "Checking next happening (time 6)\n",
      "Deleting (holding d)\n",
      "Adding (clear d)\n",
      "Adding (handempty)\n",
      "Adding (ontable d)\n",
      "\n",
      "Checking next happening (time 7)\n",
      "Deleting (on c a)\n",
      "Deleting (clear c)\n",
      "Deleting (handempty)\n",
      "Adding (holding c)\n",
      "Adding (clear a)\n",
      "\n",
      "Checking next happening (time 8)\n",
      "Deleting (clear d)\n",
      "Deleting (holding c)\n",
      "Adding (handempty)\n",
      "Adding (clear c)\n",
      "Adding (on c d)\n",
      "\n",
      "Checking next happening (time 9)\n",
      "Deleting (clear b)\n",
      "Deleting (ontable b)\n",
      "Deleting (handempty)\n",
      "Adding (holding b)\n",
      "\n",
      "Checking next happening (time 10)\n",
      "Deleting (clear c)\n",
      "Deleting (holding b)\n",
      "Adding (handempty)\n",
      "Adding (clear b)\n",
      "Adding (on b c)\n",
      "Plan executed successfully - checking goal\n",
      "Plan valid\n",
      "Final value: 10 \n",
      "\n",
      "Successful plans:\n",
      "Value: 10\n",
      " sas_plan 10 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/data/shibo/LLM-search/examples/rap_blocksworld/data/generated_domain.pddl'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "domain_pddl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/data/shibo/LLM-search/LLMs-Planning/llm_planning_analysis/instances/blocksworld/generated_basic/instance-131.pddl\n"
     ]
    }
   ],
   "source": [
    "print(cur_instance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'(unstack a c)\\n(put-down a)\\n(unstack c d)\\n(stack c a)\\n(unstack d b)\\n(put-down d)\\n(unstack c a)\\n(stack c d)\\n(pick-up b)\\n(stack b c)\\n'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gt_plan_text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_path_sup = \"LLMs-Planning/llm_planning_analysis/instances/blocksworld/generated_basic_3\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 101/101 [03:35<00:00,  2.13s/it]\n"
     ]
    }
   ],
   "source": [
    "from tqdm import *\n",
    "my_data_sup = []\n",
    "for i in tqdm(os.listdir(data_path_sup)):\n",
    "    if i.endswith(\".pddl\"):\n",
    "        data_file = os.path.join(data_path_sup, i)\n",
    "        # print(i)\n",
    "    else:\n",
    "        print(\"Not pddl file\", i)\n",
    "        continue\n",
    "    cur_instance = data_file\n",
    "    problem = get_problem(cur_instance, domain_pddl)\n",
    "    gt_plan = compute_plan(domain_pddl, cur_instance)\n",
    "    gt_plan_text = get_plan_as_text(data)\n",
    "    my_data_sup.append((cur_instance, gt_plan_text, len(re.findall(\"\\(.*?\\)\", gt_plan_text))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "501"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(my_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "101"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(my_data_sup)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "json.dump(my_data, open(\"bw_basic.json\", \"w\"))\n",
    "json.dump(my_data_sup, open(\"bw_basic_sup.json\", \"w\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "json.dump(my_data + my_data_sup, open(\"full\", \"w\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "under_8 = [d for d in my_data + my_data_sup if d[-1] <= 8]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "under_6 = [d for d in my_data + my_data_sup if d[-1] <= 6]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "441\n",
      "288\n"
     ]
    }
   ],
   "source": [
    "print(len(under_8))\n",
    "print(len(under_6))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "json.dump(under_8, open(\"under_8.json\", \"w\"))\n",
    "json.dump(under_6, open(\"under_6.json\", \"w\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Reproduce Haotian's 100% results\n",
    "# CUDA_VISIBLE_DEVICES=2,3 python examples/rap_blocksworld/inference.py --data_path 'examples/rap_blocksworld/data/step_4.json' --depth_limit 4 --model_dir $LLAMA2_CKPTS --lora_dir None --batch_size 1 --output_trace_in_each_iter --mem_map [16,22]\n",
    "\n",
    "# CUDA_VISIBLE_DEVICES=4,5 python examples/rap_blocksworld/inference.py --data_path 'examples/rap_blocksworld/data/under_6.json' --depth_limit 6 --model_dir $LLAMA2_CKPTS --lora_dir None --batch_size 1 --output_trace_in_each_iter --mem_map [16,22] --n_iters 20\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_data = json.load(open(\"examples/rap_blocksworld/data/full.json\", \"r\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting matplotlib\n",
      "  Downloading matplotlib-3.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.6 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m11.6/11.6 MB\u001b[0m \u001b[31m68.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m \u001b[36m0:00:01\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: pillow>=6.2.0 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from matplotlib) (9.2.0)\n",
      "Requirement already satisfied: packaging>=20.0 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from matplotlib) (23.1)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from matplotlib) (2.8.2)\n",
      "Requirement already satisfied: numpy<2,>=1.21 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from matplotlib) (1.23.3)\n",
      "Collecting kiwisolver>=1.0.1\n",
      "  Downloading kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m106.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting fonttools>=4.22.0\n",
      "  Downloading fonttools-4.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.5 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.5/4.5 MB\u001b[0m \u001b[31m101.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
      "\u001b[?25hCollecting cycler>=0.10\n",
      "  Downloading cycler-0.12.0-py3-none-any.whl (8.2 kB)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from matplotlib) (3.0.9)\n",
      "Collecting contourpy>=1.0.1\n",
      "  Downloading contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (301 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m301.7/301.7 kB\u001b[0m \u001b[31m81.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: six>=1.5 in /data/shibo/anaconda3/envs/default/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n",
      "Installing collected packages: kiwisolver, fonttools, cycler, contourpy, matplotlib\n",
      "Successfully installed contourpy-1.1.1 cycler-0.12.0 fonttools-4.43.0 kiwisolver-1.4.5 matplotlib-3.8.0\n"
     ]
    }
   ],
   "source": [
    "!pip install matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 47.,  86., 155., 153., 113.,  46.,   1.,   1.]),\n",
       " array([ 2.  ,  3.75,  5.5 ,  7.25,  9.  , 10.75, 12.5 , 14.25, 16.  ]),\n",
       " <BarContainer object of 8 artists>)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.hist([d[-1] for d in all_data], bins=8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "47\n",
      "86\n",
      "155\n",
      "153\n",
      "113\n",
      "46\n",
      "1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "for i in range(2, 30, 2):\n",
    "    step_data = [d for d in all_data if d[-1] == i]\n",
    "    if len(step_data) == 0:\n",
    "        continue\n",
    "    json.dump(step_data, open(f\"examples/rap_blocksworld/data/new_data/step_{i}.json\", \"w\"))\n",
    "    print(len(step_data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llama",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
